# 此通用爬虫现在很多网站会失效，因为都完善了反爬虫机制，所以更多的可能要自己针对于不同网站自己写一个

import requests
from pyquery import PyQuery as pq

from IPProxyPool.utils.http import get_request_headers
from IPProxyPool.domain import Proxy


# 目标: 实现一个可以通过指定不同URL列表, 分组的html和详情的html, 从不同页面上提取数据;
# 步骤:
# 创建spiders的包, 创建base_spider.py文件
# 定义一个类, 继承object
# 提供三个类成员变量:
# urls: 代理IP网址的URL的列表
# group_css: 分组html, 获取包含代理IP信息标签列表的html
# detail_css: 组内html, 获取代理IP详情的信息html, 格式为: {'ip':'xx', 'port':'xx', 'area':'xx'}
# 提供初始方法, 传入爬虫URL列表, 分组html, 详情(组内)Xhtml
# 对外提供一个获取代理IP的方法
#
# 遍历URL列表, 获取URL
# 根据发送请求, 获取页面数据
# 实现随机的User-Agent请求头
# 解析页面, 提取数据
# 把数据返回

class BaseSpider():
    # urls: 代理IP网址的URL的列表
    urls = []
    # group_css: 分组html, 获取包含代理IP信息标签列表的html
    group_css = ''
    # detail_css: 组内html, 获取代理IP详情的信息html, 格式为: {'ip':'xx', 'port':'xx', 'area':'xx'}
    detail_css = {}

    # 提供初始方法, 传入爬虫URL列表, 分组html, 详情(组内)html
    def __init__(self, urls=[], group_css='', detail_css={}):
        if urls:
            self.urls = urls
        if group_css:
            self.group_css = group_css
        if detail_css:
            self.detail_css = detail_css

    def get_page_from_url(self, url):
        # 发送请求提取液面
        response = requests.get(url, headers=get_request_headers())
        return response.content.decode()

    def get_proxies_from_page(self, page):
        # 解析数据，封装成Proxy对象返回
        html = pq(page)
        # 获取标签列表
        trs = html(self.group_css)
        # 遍历trs获取代理ip信息
        for tr in trs.items():
            ip = tr(self.detail_css['ip']).text()
            port = tr(self.detail_css['port']).text()
            area = tr(self.detail_css['area']).text()
            proxy = Proxy(ip, port, area=area)
            yield proxy

    def get_proxies(self):
        # 遍历url发送请求
        for url in self.urls:
            # 获取页面
            page = self.get_page_from_url(url)
            # 解析页面
            proxies = self.get_proxies_from_page(page)
            # 返回Proxy对象
            yield from proxies  # proxies对象已经从上面的函数yield过来的，所以yield from *** 可以实现再次yield返回


if __name__ == '__main__':

    config = {
        'urls': ['https://ip.ihuan.me/address/5Lit5Zu9.html?page=5crfe930'],
        'group_css': 'div.table-responsive > table >tbody> tr',
        'detail_css': {
            'ip': 'td:nth-child(1) > a',
            'port': 'td:nth-child(2)',
            'area': 'td:nth-child(3)>a'
        }
    }

    spider = BaseSpider(**config)
    for i in spider.get_proxies():
        print(i)
